const { messageAPI, teacherAPI, API_CONFIG } = require('../../utils/api.js');
const ws = require('../../utils/ws.js');

Page({
  data: {
    peerId: null,
    peerName: '',
    peerAvatar: '',
    messages: [],
    inputContent: '',
    anchorId: 'bottom',
    statusBarHeight: 0,
    showHistory: false,
    showToolbox: false,
    // 历史记录筛选
    historySearchText: '',
    historyDate: '',
    historyFiltered: []
  },
  openMore: function() {
    this.setData({ showToolbox: !this.data.showToolbox });
  },
  closeToolbox: function() {
    this.setData({ showToolbox: false });
  },
  onLoad: function(options) {
    const peerId = Number(options.peerId || 0);
    const peerName = decodeURIComponent(options.peerName || '') || '会话';
    // 读取状态栏高度，避免自定义导航与系统状态栏重叠
    let sbh = 0;
    try {
      const info = wx.getSystemInfoSync();
      sbh = Number(info.statusBarHeight || 0) || 0;
    } catch (_) {}
    this.setData({ peerId, peerName, statusBarHeight: sbh });
    // 拉取教师头像
    if (peerId) {
      try {
        teacherAPI.getAvatar(peerId).then(url => {
          this.setData({ peerAvatar: url || '/static/teacher-avatar.svg' });
        }).catch(() => {
          this.setData({ peerAvatar: '/static/teacher-avatar.svg' });
        });
      } catch (_) {
        this.setData({ peerAvatar: '/static/teacher-avatar.svg' });
      }
    }
    wx.setNavigationBarTitle({ title: `与${peerName}聊天` });
    this.initWS();
    this.loadHistory();
  },
  openHistory: function() {
    // 直接展示当前合并后的 messages 列表
    this.closeToolbox();
    const list = this.data.messages || [];
    this.setData({ showHistory: true, historyFiltered: list });
  },
  closeHistory: function() {
    this.setData({ showHistory: false });
  },
  clearChat: function() {
    this.closeToolbox();
    wx.showModal({
      title: '清空聊天记录',
      content: '仅清空本地显示记录，不删除服务器消息。确认清空？',
      confirmText: '清空',
      confirmColor: '#ff4757',
      success: (res) => {
        if (res.confirm) {
          this.setData({ messages: [] });
          wx.showToast({ title: '已清空本地记录', icon: 'success' });
        }
      }
    });
  },
  // 从相册选择图片并上传发送
  chooseImageFromAlbum: function() {
    this.closeToolbox();
    wx.chooseImage({
      count: 1,
      sizeType: ['compressed'],
      sourceType: ['album'],
      success: (res) => {
        const path = (res.tempFilePaths && res.tempFilePaths[0]) || res.tempFilePath || '';
        if (!path) { wx.showToast({ title: '未选择图片', icon: 'none' }); return; }
        wx.showLoading({ title: '上传中...' });
        wx.uploadFile({
          url: API_CONFIG.BASE_URL + '/file/upload',
          filePath: path,
          name: 'file',
          formData: { folder: 'chat' },
          success: (upRes) => {
            try {
              const data = typeof upRes.data === 'string' ? JSON.parse(upRes.data) : upRes.data;
              const fileUrl = data && (data.fileUrl || data.url || data.data?.fileUrl);
              if (!fileUrl) throw new Error('未获取到文件地址');
              this._sendImageMessage(String(fileUrl));
            } catch (e) {
              console.error('解析上传响应失败', e);
              wx.showToast({ title: '上传解析失败', icon: 'none' });
            } finally {
              wx.hideLoading();
            }
          },
          fail: (err) => {
            wx.hideLoading();
            console.error('上传失败', err);
            wx.showToast({ title: '上传失败', icon: 'none' });
          }
        });
      },
      fail: () => wx.showToast({ title: '打开相册失败', icon: 'none' })
    });
  },
  // 选择文件并上传发送（支持 doc/docx/pdf/ppt/xls 等）
  chooseFile: function() {
    this.closeToolbox();
    try {
      wx.chooseMessageFile({
        count: 1,
        type: 'file',
        extension: ['doc','docx','pdf','ppt','pptx','xls','xlsx','txt','zip'],
        success: (res) => {
          const f = (res && res.tempFiles && res.tempFiles[0]) || {};
          const path = f.path || f.tempFilePath || '';
          const name = f.name || '文件';
          if (!path) { wx.showToast({ title: '未选择文件', icon: 'none' }); return; }
          wx.showLoading({ title: '上传中...' });
          wx.uploadFile({
            url: API_CONFIG.BASE_URL + '/file/upload',
            filePath: path,
            name: 'file',
            formData: { folder: 'chat' },
            success: (upRes) => {
              try {
                const data = typeof upRes.data === 'string' ? JSON.parse(upRes.data) : upRes.data;
                const fileUrl = data && (data.fileUrl || data.url || data.data?.fileUrl);
                if (!fileUrl) throw new Error('未获取到文件地址');
                this._sendFileMessage(String(fileUrl), String(name));
              } catch (e) {
                console.error('解析上传响应失败', e);
                wx.showToast({ title: '上传解析失败', icon: 'none' });
              } finally {
                wx.hideLoading();
              }
            },
            fail: (err) => {
              wx.hideLoading();
              console.error('上传失败', err);
              wx.showToast({ title: '上传失败', icon: 'none' });
            }
          });
        },
        fail: (err) => {
          if (String(err?.errMsg || '').includes('cancel')) return;
          wx.showToast({ title: '选择文件失败', icon: 'none' });
        }
      });
    } catch (e) {
      wx.showToast({ title: '当前环境不支持选择文件', icon: 'none' });
    }
  },
  _sendImageMessage: function(fileUrl) {
    try {
      const user = wx.getStorageSync('userInfo') || {};
      const senderId = user.userId || user.id || user.openid || user.openId || 2;
      const receiverId = Number(this.data.peerId);
      wx.showLoading({ title: '发送中...' });
      messageAPI.send({ senderId, senderType: 1, receiverId, receiverType: 2, content: String(fileUrl) })
        .then(() => {
          wx.hideLoading();
          const bubble = { id: Date.now(), type: 'image', url: String(fileUrl), time: '刚刚', mine: true };
          this.setData({ messages: [...this.data.messages, bubble] }, () => this.scrollToBottom());
        })
        .catch((err) => {
          wx.hideLoading();
          console.error('图片消息发送失败', err);
          wx.showToast({ title: '发送失败', icon: 'none' });
        });
    } catch (e) {
      wx.hideLoading();
      console.error('读取用户信息失败', e);
      wx.showToast({ title: '发送失败', icon: 'none' });
    }
  },
  _sendFileMessage: function(fileUrl, name) {
    try {
      const user = wx.getStorageSync('userInfo') || {};
      const senderId = user.userId || user.id || user.openid || user.openId || 2;
      const receiverId = Number(this.data.peerId);
      wx.showLoading({ title: '发送中...' });
      messageAPI.send({ senderId, senderType: 1, receiverId, receiverType: 2, content: String(fileUrl) })
        .then(() => {
          wx.hideLoading();
          const bubble = { id: Date.now(), type: 'file', url: String(fileUrl), name: String(name || '文件'), time: '刚刚', mine: true };
          this.setData({ messages: [...this.data.messages, bubble] }, () => this.scrollToBottom());
        })
        .catch((err) => {
          wx.hideLoading();
          console.error('文件消息发送失败', err);
          wx.showToast({ title: '发送失败', icon: 'none' });
        });
    } catch (e) {
      wx.hideLoading();
      console.error('读取用户信息失败', e);
      wx.showToast({ title: '发送失败', icon: 'none' });
    }
  },
  onShow: function() {
    // 页面重新展示时，强制确保WS连接（避免 isOpen 误判导致不重连）
    try {
      const user = wx.getStorageSync('userInfo') || {};
      const uid = user.userId || user.id || user.openid || user.openId || 2;
      ws.connect({ url: 'ws://localhost:1001/ws/chat', userId: uid, userType: 1 });
    } catch (_) {}
    // 兜底刷新一次历史，避免推送丢失
    this.loadHistory();
  },
  onUnload: function() {
    try {
      if (this._wsHandler) { ws.removeListener(this._wsHandler); }
      ws.close();
    } catch (_) {}
  },
  onBack: function() {
    // 返回到消息页面（从消息页 navigateTo 进入，因此直接返回即可）
    wx.navigateBack({ fail: () => wx.redirectTo({ url: '/pages/message/message' }) });
  },
  initWS: function() {
    try {
      const user = wx.getStorageSync('userInfo') || {};
      const uid = user.userId || user.id || user.openid || user.openId || 2;
      // 学生端会话WS应连接到学生服务（端口1001），以接收教师端的实时推送
      ws.connect({ url: 'ws://localhost:1001/ws/chat', userId: uid, userType: 1 });
      // 确保不会重复注册监听
      if (this._wsHandler) { ws.removeListener(this._wsHandler); }
      this._wsHandler = (data) => {
        try {
          // 忽略心跳
          if (typeof data === 'string' && data === 'PING') return;
          // 收到推送后刷新历史（兜底，避免字段不一致导致遗漏）
          const sid = Number((data && (data.senderId || data.fromId)) || 0);
          const rid = Number((data && (data.receiverId || data.toId)) || 0);
          const peerId = Number(this.data.peerId) || 0;
          const myId = uid;
          const isMineTarget = rid === myId || !rid; // 后端不带 rid 也做兜底刷新
          const isPeer = sid === peerId;
          // 若明确为当前会话的教师发来，先加一条本地气泡提升感知
          if (isMineTarget && isPeer && data && data.content) {
            const raw = String(data.content || '').trim();
            const parsed = (function parseContentInline(s){
              try {
                const str = String(s || '').trim();
                const base = str.split('?')[0].split('#')[0].trim();
                const ext = base.includes('.') ? base.split('.').pop().toLowerCase() : '';
                const imgExts = ['png','jpg','jpeg','gif','webp','bmp'];
                const fileExts = ['doc','docx','pdf','ppt','pptx','xls','xlsx','txt','zip'];
                if (imgExts.includes(ext)) return { type: 'image', url: str };
                if (fileExts.includes(ext)) {
                  const name = base.substring(base.lastIndexOf('/')+1) || '文件';
                  return { type: 'file', url: str, name };
                }
                return { type: 'text', content: str.replace(/\r\n|\r|\n/g, ' ').replace(/\s{2,}/g, ' ').trim() };
              } catch (_) {
                return { type: 'text', content: String(s || '') };
              }
            })(raw);
            const bubble = { id: Date.now(), ...parsed, time: '刚刚', mine: false };
            this.setData({ messages: [...this.data.messages, bubble] }, () => this.scrollToBottom());
          }
        } catch (err) {
          console.warn('WS消息处理异常', err);
        } finally {
          // 无论是否能完全判定，都刷新一次历史，确保不遗漏
          this.loadHistory();
        }
      };
      ws.onMessage(this._wsHandler);
    } catch (e) {
      console.warn('WS连接失败', e);
    }
  },
  loadHistory: function() {
    try {
      const user = wx.getStorageSync('userInfo') || {};
      const myId = user.userId || user.id || user.openid || user.openId || 2;
      const peerId = Number(this.data.peerId) || 0;
      // 学生收到的消息（教师->学生）与教师收到的消息（学生->教师）分别查询后合并
      Promise.all([
        messageAPI.list(myId, 1),       // 收到的：对我而言的收件箱
        peerId ? messageAPI.list(peerId, 2) : Promise.resolve([]) // 我发出的：查询对方（教师）的收件箱
      ]).then(([incomingList, peerInboxList]) => {
        // 将当前会话的未读消息置为已读（后端角标与高亮清除）
        try {
          const unreadIds = (Array.isArray(incomingList) ? incomingList : [])
            .filter(m => Number(m.senderId) === peerId && (m.isRead !== 1))
            .map(m => m.id)
            .filter(Boolean);
          if (unreadIds.length) {
            Promise.all(unreadIds.map(id => messageAPI.markRead(id).catch(() => true))).catch(() => {});
          }
        } catch (_) {}
        const incoming = (Array.isArray(incomingList) ? incomingList : [])
          .filter(m => Number(m.senderId) === peerId)
          .map(m => {
            const parsed = parseContent(m.content || '');
            const dkey = toDateKey(m.sendTime || m.time);
            return {
              id: m.id,
              ...parsed,
              time: formatTime(m.sendTime || m.time),
              t: toTs(m.sendTime || m.time),
              dateKey: dkey,
              mine: false
            };
          });

        const outgoing = (Array.isArray(peerInboxList) ? peerInboxList : [])
          .filter(m => Number(m.senderId) === myId && Number(m.receiverId) === peerId)
          .map(m => {
            const parsed = parseContent(m.content || '');
            const dkey = toDateKey(m.sendTime || m.time);
            return {
              id: m.id,
              ...parsed,
              time: formatTime(m.sendTime || m.time),
              t: toTs(m.sendTime || m.time),
              dateKey: dkey,
              mine: true
            };
          });

        const merged = [...incoming, ...outgoing]
          .sort((a, b) => (a.t - b.t)); // 按时间升序
        const msgs = merged.map(({t, ...rest}) => rest);
        this.setData({ messages: msgs }, () => {
          this.scrollToBottom();
          if (this.data.showHistory) this.applyHistoryFilter();
        });
      }).catch((err) => {
        console.error('加载会话历史失败', err);
      });
    } catch (e) {
      console.error('读取用户信息失败', e);
    }
    function formatTime(t) {
      try {
        const d = new Date(typeof t === 'number' ? t : (t || new Date()));
        const hh = String(d.getHours()).padStart(2, '0');
        const mm = String(d.getMinutes()).padStart(2, '0');
        return `${hh}:${mm}`;
      } catch (_) {
        return '刚刚';
      }
    }
    function toTs(t) {
      try {
        const d = new Date(typeof t === 'number' ? t : (t || new Date()));
        return d.getTime();
      } catch (_) {
        return Date.now();
      }
    }
    function toDateKey(t) {
      try {
        const d = new Date(typeof t === 'number' ? t : (t || new Date()));
        const yyyy = String(d.getFullYear());
        const mm = String(d.getMonth() + 1).padStart(2, '0');
        const dd = String(d.getDate()).padStart(2, '0');
        return `${yyyy}-${mm}-${dd}`;
      } catch (_) {
        const d = new Date();
        const yyyy = String(d.getFullYear());
        const mm = String(d.getMonth() + 1).padStart(2, '0');
        const dd = String(d.getDate()).padStart(2, '0');
        return `${yyyy}-${mm}-${dd}`;
      }
    }
    function normalizeText(s) {
      try {
        return String(s).replace(/\r\n|\r|\n/g, ' ').replace(/\s{2,}/g, ' ').trim();
      } catch (_) {
        return s || '';
      }
    }
    function parseContent(s) {
      try {
        // 更健壮的解析：剔除空白与锚点、查询串后判断扩展名
        const str = String(s || '').trim();
        const base = str.split('?')[0].split('#')[0].trim();
        const ext = base.includes('.') ? base.split('.').pop().toLowerCase() : '';
        const imgExts = ['png','jpg','jpeg','gif','webp','bmp'];
        const fileExts = ['doc','docx','pdf','ppt','pptx','xls','xlsx','txt','zip'];
        if (imgExts.includes(ext)) return { type: 'image', url: str };
        if (fileExts.includes(ext)) {
          const name = base.substring(base.lastIndexOf('/')+1) || '文件';
          return { type: 'file', url: str, name };
        }
        return { type: 'text', content: normalizeText(str) };
      } catch (_) {
        return { type: 'text', content: s || '' };
      }
    }
  },
  // 历史记录筛选：日期与内容模糊匹配
  applyHistoryFilter: function() {
    const date = String(this.data.historyDate || '').trim();
    const text = String(this.data.historySearchText || '').trim().toLowerCase();
    const list = (this.data.messages || []).filter(m => {
      let ok = true;
      if (date) ok = ok && (m.dateKey === date);
      if (text) {
        const src = String(m.content || (m.type === 'image' ? m.url : '') || '').toLowerCase();
        ok = ok && src.indexOf(text) !== -1;
      }
      return ok;
    });
    this.setData({ historyFiltered: list });
  },
  onHistorySearchInput: function(e) {
    const v = (e && e.detail && e.detail.value) || '';
    this.setData({ historySearchText: v }, () => this.applyHistoryFilter());
  },
  onHistoryDateChange: function(e) {
    const v = (e && e.detail && e.detail.value) || '';
    this.setData({ historyDate: v }, () => this.applyHistoryFilter());
  },
  scrollToBottom: function() {
    this.setData({ anchorId: 'bottom' });
  },
  onInput: function(e) {
    this.setData({ inputContent: e.detail.value || '' });
  },
  onSend: function() {
    const content = normalizeText(this.data.inputContent || '');
    if (!content) {
      wx.showToast({ title: '请输入消息', icon: 'none' });
      return;
    }
    const receiverId = Number(this.data.peerId);
    wx.showLoading({ title: '发送中...' });
    try {
      const user = wx.getStorageSync('userInfo') || {};
      const senderId = user.userId || user.id || user.openid || user.openId || 2;
      messageAPI.send({ senderId, senderType: 1, receiverId, receiverType: 2, content }).then(() => {
        wx.hideLoading();
        this.setData({ inputContent: '' });
        const bubble = { id: Date.now(), content, time: '刚刚', mine: true };
        this.setData({ messages: [...this.data.messages, bubble] }, () => this.scrollToBottom());
      }).catch((err) => {
        wx.hideLoading();
        console.error('发送失败', err);
        wx.showToast({ title: '发送失败', icon: 'none' });
      });
    } catch (e) {
      wx.hideLoading();
      console.error('读取用户信息失败', e);
      wx.showToast({ title: '发送失败', icon: 'none' });
    }
    function normalizeText(s) {
      try {
        return String(s).replace(/\r\n|\r|\n/g, ' ').replace(/\s{2,}/g, ' ').trim();
      } catch (_) {
        return s || '';
      }
    }
  }
  ,previewImage: function(e) {
    const url = (e && e.currentTarget && e.currentTarget.dataset && e.currentTarget.dataset.url) || '';
    if (!url) return;
    wx.previewImage({ current: url, urls: [url] });
  }
  ,openFile: function(e) {
    let url = (e && e.currentTarget && e.currentTarget.dataset && e.currentTarget.dataset.url) || '';
    const name = (e && e.currentTarget && e.currentTarget.dataset && e.currentTarget.dataset.name) || '文件';
    if (!url) return;
    // 预处理：在开发/预览环境中尽量使用 https 以提高兼容性
    url = normalizeDownloadURL(url);
    wx.showLoading({ title: '打开中...' });
    wx.downloadFile({
      url: url,
      success: (res) => {
        const filePath = res.tempFilePath || res.filePath;
        if (!filePath) { wx.hideLoading(); wx.showToast({ title: '下载失败', icon: 'none' }); return; }
        wx.openDocument({
          filePath,
          fileType: undefined,
          showMenu: true,
          success: () => { wx.hideLoading(); },
          fail: (err) => {
            wx.hideLoading();
            console.error('打开文档失败', err);
            try {
              wx.showActionSheet({
                itemList: ['复制链接'],
                success: (aRes) => {
                  if (aRes.tapIndex === 0) {
                    wx.setClipboardData({ data: url, success: () => wx.showToast({ title: '链接已复制', icon: 'none' }) });
                  }
                }
              });
            } catch (_) {
              wx.showToast({ title: '无法打开文档', icon: 'none' });
            }
          }
        });
      },
      fail: (err) => {
        wx.hideLoading();
        console.error('下载失败', err);
        // 降级：复制链接，便于外部浏览器打开
        try {
          wx.showActionSheet({
            itemList: ['复制链接'],
            success: (aRes) => {
              if (aRes.tapIndex === 0) {
                wx.setClipboardData({ data: url, success: () => wx.showToast({ title: '链接已复制', icon: 'none' }) });
              }
            }
          });
        } catch (_) {
          wx.showToast({ title: '下载失败', icon: 'none' });
        }
      }
    });
    function normalizeDownloadURL(u) {
      try {
        let s = String(u || '').trim();
        // 不强制协议升级，避免因后端TLS版本过低导致失败；仅补全相对路径
        if (!/^https?:\/\//i.test(s)) s = API_CONFIG.BASE_URL + (s.startsWith('/') ? s : ('/' + s));
        return s;
      } catch (_) { return u; }
    }
  }
});